package com.wenjiang.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wenjiang.common.constat.RedisKey;
import com.wenjiang.common.dto.SearchDetailParam;
import com.wenjiang.common.dto.SearchGoodByTypeParam;
import com.wenjiang.common.exception.SearchException;
import com.wenjiang.common.lang.Result;
import com.wenjiang.common.vo.SearchKeyWordInfo;

import com.wenjiang.entity.*;
import com.wenjiang.mapper.GoodIndexDao;
import com.wenjiang.mapper.MallGoodMapper;
import com.wenjiang.mapper.MallGoodTypeMapper;
import com.wenjiang.service.GoodSearchService;

import com.wenjiang.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.stereotype.Service;

import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class GoodServiceImpl implements GoodSearchService {

    //根据名称进行注入
    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    GoodIndexDao goodIndexDao;

    @Autowired
    MallGoodMapper mallGoodMapper;

    @Autowired
    MallGoodTypeMapper mallGoodTypeMapper;



    // 返回关键词 热度排名
    @Override
    public Result getHotKeyWord() {

        return Result.succ(redisUtils.getZSet(RedisKey.searchHotKey, 0, 5));
    }

    @Override
    public Result searchGoodByName(String GoodName)  {
        // 构造返回结果
        List<SearchKeyWordInfo> result= new ArrayList<>();

        //构建搜索请求
        SearchRequest searchRequest= new SearchRequest("good");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //构建搜索条件
        searchSourceBuilder.from(0).size(10).sort("goodSell", SortOrder.DESC).fetchSource("goodName", null).query(QueryBuilders.termQuery("goodName", GoodName));

      searchRequest.source(searchSourceBuilder);
      try{
          SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
          //构造返回结果
          SearchHit[] hits = searchResponse.getHits().getHits();


          for (SearchHit hit : hits) {
              System.out.println(hit.getSourceAsString());

              JSONObject object = JSONObject.parseObject(hit.getSourceAsString());

              String goodName = object.getString("goodName");

              SearchKeyWordInfo searchKeyWordInfo =new SearchKeyWordInfo();

              searchKeyWordInfo.setValue(goodName);

              result.add(searchKeyWordInfo);

          }
      }catch (Exception e){
          e.printStackTrace();
          throw  new SearchException();

      }


        return Result.succ(result);
    }

    @Override
    public Result searchGoodDetail(SearchDetailParam searchDetailParam) {

        //构建返回结果
        SearchGoodDetailVo searchGoodDetailVo=  new SearchGoodDetailVo();

        List<GoodIndex> result = new ArrayList<>();

        SearchRequest searchRequest = new SearchRequest("good");

        SearchSourceBuilder searchSourceBuilder= new SearchSourceBuilder();

        //构建高亮查询
        HighlightBuilder highlightBuilder= new HighlightBuilder();
        highlightBuilder.field("goodName").requireFieldMatch(false
        ).preTags("<span style='color:red;'>").postTags("</span>");

        //必带的条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //关键字名称 （term 查询可能会查不到）
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("goodName", searchDetailParam.getKeyword()));

        //计算当前从那开始查找 (当前页数-1)*页码
        int index=  (searchDetailParam.getCurrentPage()-1)*(searchDetailParam.getPageSize());

        searchSourceBuilder.sort("goodSell",
                SortOrder.DESC).highlighter(highlightBuilder);



        if((searchDetailParam.getLowPrice()!=null)&&(searchDetailParam.getHighPrice()!=null)) {
            //添加价格区间条件
            boolQueryBuilder.must(QueryBuilders.rangeQuery("goodNowPrice").gte(searchDetailParam.getLowPrice()).lte(searchDetailParam.getHighPrice()));
        }


        //添加所有条件
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            //先查符合条件总数
            SearchHit[] hits = searchResponse.getHits().getHits();
            searchGoodDetailVo.setTotal(hits.length);


            //再添加分页条件
            searchSourceBuilder.from(index).size(searchDetailParam.getPageSize());
            searchRequest.source(searchSourceBuilder);
            //查询分页结果
            searchResponse=restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            hits=searchResponse.getHits().getHits();
            for(SearchHit hit:hits){
                String sourceAsString = hit.getSourceAsString();
                //转化为对象
                GoodIndex goodIndex = JSONObject.parseObject(sourceAsString,GoodIndex.class);
                //获取高亮属性
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                //遍历高亮属性  （因为只有一个就直接设置了）
                highlightFields.forEach((k,v)->{
                    goodIndex.setGoodName(v.fragments()[0].toString());
                });

                result.add(goodIndex);
            }
             // 如果查得到结果 给关键词热度+1
            if (hits.length!=0){
                //给关键热度进行加热度操作
                redisUtils.incrementZSet(RedisKey.searchHotKey, searchDetailParam.getKeyword(), 1);
            }


            searchGoodDetailVo.setGoodList(result);
        }catch (Exception e){
             e.printStackTrace();

        }


        return Result.succ(searchGoodDetailVo);
    }


    @Override
    public Result searchGoodByType(SearchGoodByTypeParam searchGoodByTypeParam) {
        //查询该商品的其他分类
        List<MallGoodType> otherType = mallGoodTypeMapper.getOtherType(searchGoodByTypeParam.getTypeId());

        //查询对应商品的信息
        QueryWrapper<MallGood> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("good_type", searchGoodByTypeParam.getTypeId());
        //计算当前页面大小
        Integer currentIndex= (searchGoodByTypeParam.getCurrentPage()-1)*searchGoodByTypeParam.getPageSize();

        queryWrapper.orderByDesc(searchGoodByTypeParam.isDateDesc(), "good_create_time");
        queryWrapper.orderByAsc(searchGoodByTypeParam.isPriceAsc(), "good_now_price");
        queryWrapper.orderByDesc(searchGoodByTypeParam.isSellDesc(), "good_sell");
        Page<MallGood> page = new Page(searchGoodByTypeParam.getCurrentPage(), searchGoodByTypeParam.getPageSize());
        Page<MallGood> selectPage = mallGoodMapper.selectPage(page, queryWrapper);

        List<MallGood> goodList = selectPage.getRecords();





        //创建返回的结果集
        SearchGoodByTypeVo searchGoodByTypeVo = new SearchGoodByTypeVo();
        searchGoodByTypeVo.setGoodList(goodList);
        searchGoodByTypeVo.setOtherType(otherType);

        //
        return Result.succ(searchGoodByTypeVo);
    }
}
